﻿using NthDownload.Contracts;
using NthDownload.Common.ViewModels;

namespace NthDownload.ViewModels
{
    public class MessageDialogViewModel : ViewModelScreenBase
    {
        #region Class Members

        private string _message;
        private bool _showYes;
        private bool _showOk;
        private bool _showNo;
        private bool _showCancel;
        private bool _showRetry;
        private bool _focusYes;
        private bool _focusOk;
        private bool _focusNo;
        private bool _focusCancel;
        private bool _focusRetry;
        private ViewModelResults _defaultResult;

        #endregion Class Members

        #region Constructors

        public MessageDialogViewModel(string message, ViewModelResults defaultResult)
        {
            //
            // Set defaults
            //
            Message = message;
            ShowCancel = false;
            ShowNo = false;
            ShowOk = false;
            ShowRetry = false;
            ShowYes = false;
            FocusCancel = false;
            FocusNo = false;
            FocusOk = false;
            FocusRetry = false;
            FocusYes = false;
            DefaultResult = defaultResult;
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// The message to display
        /// </summary>
        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = value;
                NotifyOfPropertyChange(() => Message);
            }
        }

        /// <summary>
        /// The result which is selected by default
        /// </summary>
        public ViewModelResults DefaultResult
        {
            get
            {
                return _defaultResult;
            }
            set
            {
                _defaultResult = value;
                NotifyOfPropertyChange(() => DefaultResult);
                UpdateDefaultResultFocus();
            }
        }

        #region Show

        /// <summary>
        /// Indicates if the yes option show be available
        /// </summary>
        public bool ShowYes
        {
            get
            {
                return _showYes;
            }
            set
            {
                _showYes = value;
                NotifyOfPropertyChange(() => ShowYes);
            }
        }

        /// <summary>
        /// Indicates if the ok option show be available
        /// </summary>
        public bool ShowOk
        {
            get
            {
                return _showOk;
            }
            set
            {
                _showOk = value;
                NotifyOfPropertyChange(() => ShowOk);
            }
        }

        /// <summary>
        /// Indicates if the no option show be available
        /// </summary>
        public bool ShowNo
        {
            get
            {
                return _showNo;
            }
            set
            {
                _showNo = value;
                NotifyOfPropertyChange(() => ShowNo);
            }
        }

        /// <summary>
        /// Indicates if the cancel option show be available
        /// </summary>
        public bool ShowCancel
        {
            get
            {
                return _showCancel;
            }
            set
            {
                _showCancel = value;
                NotifyOfPropertyChange(() => ShowCancel);
            }
        }

        /// <summary>
        /// Indicates if the retry option show be available
        /// </summary>
        public bool ShowRetry
        {
            get
            {
                return _showRetry;
            }
            set
            {
                _showRetry = value;
                NotifyOfPropertyChange(() => ShowRetry);
            }
        }

        #endregion Show

        #region Focus

        /// <summary>
        /// Used for swicthing focus to yes result
        /// </summary>
        public bool FocusYes
        {
            get
            {
                return _focusYes;
            }
            set
            {
                _focusYes = value;
                NotifyOfPropertyChange(() => FocusYes);
            }
        }

        /// <summary>
        /// Used for swicthing focus to ok result
        /// </summary>
        public bool FocusOk
        {
            get
            {
                return _focusOk;
            }
            set
            {
                _focusOk = value;
                NotifyOfPropertyChange(() => FocusOk);
            }
        }

        /// <summary>
        /// Used for swicthing focus to no result
        /// </summary>
        public bool FocusNo
        {
            get
            {
                return _focusNo;
            }
            set
            {
                _focusNo = value;
                NotifyOfPropertyChange(() => FocusNo);
            }
        }

        /// <summary>
        /// Used for swicthing focus to cancel result
        /// </summary>
        public bool FocusCancel
        {
            get
            {
                return _focusCancel;
            }
            set
            {
                _focusCancel = value;
                NotifyOfPropertyChange(() => FocusCancel);
            }
        }

        /// <summary>
        /// Used for swicthing focus to retry result
        /// </summary>
        public bool FocusRetry
        {
            get
            {
                return _focusRetry;
            }
            set
            {
                _focusRetry = value;
                NotifyOfPropertyChange(() => FocusRetry);
            }
        }

        #endregion Focus

        #endregion Properties

        #region Methods

        /// <summary>
        /// Closes the dialog with a retry result
        /// </summary>
        public void Retry()
        {
            Result = ViewModelResults.Retry;
            TryClose();
        }

        /// <summary>
        /// Closes the dialog with a yes result
        /// </summary>
        public void Yes()
        {
            Result = ViewModelResults.Yes;
            TryClose();
        }

        /// <summary>
        /// Closes the dialog with a ok result
        /// </summary>
        public void Ok()
        {
            Result = ViewModelResults.Ok;
            TryClose();
        }

        /// <summary>
        /// Closes the dialog with a no result
        /// </summary>
        public void No()
        {
            Result = ViewModelResults.No;
            TryClose();
        }

        /// <summary>
        /// Closes the dialog with a cancel result
        /// </summary>
        public void Cancel()
        {
            Result = ViewModelResults.Cancel;
            TryClose();
        }

        #endregion Methods

        #region Private Methods

        /// <summary>
        /// Updates the currently focused result to align with the current value of the default result
        /// </summary>
        private void UpdateDefaultResultFocus()
        {
            if (DefaultResult == ViewModelResults.Yes) FocusYes = !FocusYes;
            else if (DefaultResult == ViewModelResults.Ok) FocusOk = !FocusOk;
            else if (DefaultResult == ViewModelResults.No) FocusNo = !FocusNo;
            else if (DefaultResult == ViewModelResults.Cancel) FocusCancel = !FocusCancel;
            else if (DefaultResult == ViewModelResults.Retry) FocusRetry = !FocusRetry; 
        }

        #endregion Private Methods

        #region Static Methods

        /// <summary>
        /// Shows a message dialog setup for an error
        /// </summary>
        /// <param name="errorMessage">The error message to be displayed.</param>
        public static ViewModelResults ShowError(string errorMessage)
        {
            MessageDialogViewModel messageDialogViewModel = new MessageDialogViewModel(errorMessage, ViewModelResults.Ok);
            messageDialogViewModel.ShowOk = true;

            return messageDialogViewModel.NavigationService.ShowDialog(messageDialogViewModel, false);
        }

        #endregion Static Methods
    }
}
